// Copyright 2024 Vadim Kharitonovich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package packet

type Serializable interface {
	Serialize() []byte
}

type RequestPayload interface {
	Serializable
	*Retention
}

type Requestable interface {
	Serializable
	RequiresResponse() bool
}

type Request[P RequestPayload] struct {
	*Header[RequestMessageCode]
	Payload P
}

func (r *Request[P]) Serialize() []byte {
	payload := r.Payload.Serialize()

	buf := make([]byte, RequestHeaderSize+len(payload))
	r.Header.SerializeInto(buf)
	copy(buf[RequestHeaderSize:], payload)
	return buf
}

func (r *Request[P]) RequiresResponse() bool {
	return r.Header.requiresResponse
}

func NewRequest[P RequestPayload](header *Header[RequestMessageCode]) *Request[P] {
	return &Request[P]{
		Header: header,
	}
}

func NewRetentionRequest(header *Header[RequestMessageCode], retention *Retention) *Request[*Retention] {
	r := NewRequest[*Retention](header)
	r.Payload = retention
	return r
}

func ParseRequestHeader(data []byte) (*Header[RequestMessageCode], error) {
	if len(data) < RequestHeaderSize {
		return nil, ErrMalformed
	}

	var (
		requestHeader = Header[RequestMessageCode]{
			Version: UnserializeVersion(data),
			Code:    GetMessageCode[RequestMessageCode](data),
		}
	)

	return &requestHeader, nil
}
